From a880f7f44c01192235d8f9b2969490550c4d7619 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Wed, 12 Jan 2005 14:17:52 +0000 Subject: [PATCH] bitkeeper revision 1.1159.170.90 (41e53190NTwQxrBNj2UypCRVNj7fyQ) More seg-fixup cleanups and safety fixes. --- xen/arch/x86/traps.c | 27 +++++++++++++++---------- xen/arch/x86/x86_32/seg_fixup.c | 35 ++++++++++++++++++++++----------- xen/include/asm-x86/mm.h | 2 ++ 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index ed996e30a0..2bdb160373 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -382,13 +382,27 @@ asmlinkage void do_machine_check(struct xen_regs *regs) fatal_trap(TRAP_machine_check, regs); } -asmlinkage int do_page_fault(struct xen_regs *regs) +void propagate_page_fault(unsigned long addr, u16 error_code) { trap_info_t *ti; + struct domain *d = current; + struct trap_bounce *tb = &d->thread.trap_bounce; + + ti = d->thread.traps + 14; + tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE | TBF_EXCEPTION_CR2; + tb->cr2 = addr; + tb->error_code = error_code; + tb->cs = ti->cs; + tb->eip = ti->address; + if ( TI_GET_IF(ti) ) + d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1; +} + +asmlinkage int do_page_fault(struct xen_regs *regs) +{ unsigned long off, addr, fixup; struct domain *d = current; extern int map_ldt_shadow_page(unsigned int); - struct trap_bounce *tb = &d->thread.trap_bounce; int cpu = d->processor; __asm__ __volatile__ ("movl %%cr2,%0" : "=r" (addr) : ); @@ -437,14 +451,7 @@ asmlinkage int do_page_fault(struct xen_regs *regs) if ( !GUEST_FAULT(regs) ) goto xen_fault; - ti = d->thread.traps + 14; - tb->flags = TBF_EXCEPTION | TBF_EXCEPTION_ERRCODE | TBF_EXCEPTION_CR2; - tb->cr2 = addr; - tb->error_code = regs->error_code; - tb->cs = ti->cs; - tb->eip = ti->address; - if ( TI_GET_IF(ti) ) - d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1; + propagate_page_fault(addr, regs->error_code); return 0; xen_fault: diff --git a/xen/arch/x86/x86_32/seg_fixup.c b/xen/arch/x86/x86_32/seg_fixup.c index 7c53def147..9009971d26 100644 --- a/xen/arch/x86/x86_32/seg_fixup.c +++ b/xen/arch/x86/x86_32/seg_fixup.c @@ -278,9 +278,7 @@ void *decode_reg(struct xen_regs *regs, u8 b) /* * Called from the general-protection fault handler to attempt to decode - * and emulate an instruction that depends on 4GB segments. At this point - * we assume that the instruction itself is paged into memory (the CPU - * must have triggered this in order to decode the instruction itself). + * and emulate an instruction that depends on 4GB segments. */ int gpf_emulate_4gb(struct xen_regs *regs) { @@ -315,7 +313,7 @@ int gpf_emulate_4gb(struct xen_regs *regs) if ( get_user(b, pb) ) { DPRINTK("Fault while accessing byte %d of instruction\n", pb-eip); - goto fail; + goto page_fault; } if ( (pb - eip) >= 15 ) @@ -371,10 +369,21 @@ int gpf_emulate_4gb(struct xen_regs *regs) switch ( decode & 7 ) { case 1: - offset = (long)(*(char *)pb); + if ( get_user(b, pb) ) + { + DPRINTK("Fault while extracting .\n"); + goto page_fault; + } + pb++; + offset = (signed long)(signed char)b; goto skip_modrm; case 4: - offset = *(long *)pb; + if ( get_user(offset, (u32 *)pb) ) + { + DPRINTK("Fault while extracting .\n"); + goto page_fault; + } + pb += 4; goto skip_modrm; default: goto fail; @@ -388,7 +397,7 @@ int gpf_emulate_4gb(struct xen_regs *regs) if ( get_user(modrm, pb) ) { DPRINTK("Fault while extracting modrm byte\n"); - goto fail; + goto page_fault; } pb++; @@ -420,7 +429,7 @@ int gpf_emulate_4gb(struct xen_regs *regs) if ( get_user(disp32, (u32 *)pb) ) { DPRINTK("Fault while extracting .\n"); - goto fail; + goto page_fault; } pb += 4; } @@ -432,7 +441,7 @@ int gpf_emulate_4gb(struct xen_regs *regs) if ( get_user(disp8, pb) ) { DPRINTK("Fault while extracting .\n"); - goto fail; + goto page_fault; } pb++; disp32 = (disp8 & 0x80) ? (disp8 | ~0xff) : disp8;; @@ -444,7 +453,7 @@ int gpf_emulate_4gb(struct xen_regs *regs) if ( get_user(disp32, (u32 *)pb) ) { DPRINTK("Fault while extracting .\n"); - goto fail; + goto page_fault; } pb += 4; break; @@ -478,7 +487,7 @@ int gpf_emulate_4gb(struct xen_regs *regs) d->shared_info->vcpu_data[0].evtchn_upcall_mask = 1; } - return 1; + return EXCRET_fault_fixed; fixme: DPRINTK("Undecodable instruction %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " @@ -488,4 +497,8 @@ int gpf_emulate_4gb(struct xen_regs *regs) regs->cs, regs->eip); fail: return 0; + + page_fault: + propagate_page_fault((unsigned long)pb, 4); + return EXCRET_fault_fixed; } diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 529ecbfc5c..8f35bd96e7 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -296,4 +296,6 @@ void audit_domains(void); #define audit_domains() ((void)0) #endif +void propagate_page_fault(unsigned long addr, u16 error_code); + #endif /* __ASM_X86_MM_H__ */ -- 2.30.2